package com.zktravel.aop;

import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.util.Locale;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpSession;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;

import com.alibaba.fastjson.JSON;

public class ControllerInterceptor implements MethodInterceptor {
    private static Logger logger = LoggerFactory.getLogger(ControllerInterceptor.class);

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            /*
             * Object[] args = mi.getArguments(); if (args != null && args.length > 0) { if
             * (args[0] instanceof BaseDTO) { BaseDTO dto = (BaseDTO) args[0]; if(null ==
             * dto.getSid() || null == dto.getUid()){ throw new
             * VisibleException(CodeEnum.ERROR_UID); } //获取用户信息 UserInfo userInfo =
             * getUserInfo(dto); if(null != userInfo){
             * dto.setIsVip(userInfo.getVipInfo().getFlag()); args[0] = dto; }else{ userInfo
             * = new UserInfo(); userInfo.setId(dto.getUid()); }
             * userInfo.setShopId(dto.getSid()); SessionContext.setUser(userInfo); }
             *
             * }else{ throw new VisibleException(CodeEnum.ERROR_UID); }
             */

            return mi.proceed();
        } catch (Exception e) {
            Object[] args = mi.getArguments();
            Method m = mi.getMethod();
            logger.error("------------ {}.{} Parameters: ------------", m.getDeclaringClass().getName(), m.getName());
            if (args != null && args.length > 0) {
                String[] paramNames = getMethodParamNames(mi, m);
                int i = 0;
                for (Object arg : args) {
                    if (isMvcInternalArgument(arg))
                        continue;

                    logger.error("{}: " + arg2Str(arg), paramNames.length > i ? paramNames[i] : "arg" + i);
                    i++;
                }
            }
            throw e;
        }
    }

    private String arg2Str(Object arg) {
        if (arg == null)
            return null;
        if (arg instanceof String)
            return arg.toString();

        return JSON.toJSONString(arg);
    }

    private boolean isMvcInternalArgument(Object obj) {
        if (obj == null)
            return false;
        if (obj instanceof ServletRequest)
            return true;
        if (obj instanceof ServletResponse)
            return true;
        if (obj instanceof HttpSession)
            return true;
        if (obj.getClass().getName().startsWith("javax.servlet"))
            return true;
        if (obj instanceof InputStream)
            return true;
        if (obj instanceof Reader)
            return true;
        if (obj instanceof Locale)
            return true;
        
        return false;
    }

    private String[] getMethodParamNames(MethodInvocation mi, Method m) throws Exception {
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNames = u.getParameterNames(m);
        if (paramNames == null) {
            m = mi.getThis().getClass().getMethod(m.getName(), m.getParameterTypes());
            paramNames = u.getParameterNames(m);
        }
        return paramNames != null ? paramNames : new String[0];
    }

    /*
     * private UserInfo getUserInfo(BaseDTO dto){ return
     * serverServiceFactory.getUserInfo(dto.getUid()); }
     */
}
